/**
 * 增强的拖拽交互系统
 * 提供流畅的拖拽体验和丰富的视觉反馈
 */

import { ref, computed, onMounted, onUnmounted } from 'vue'

export function useDragAndDrop(options = {}) {
  const {
    onDragStart = () => {},
    onDragMove = () => {},
    onDragEnd = () => {},
    onDrop = () => {},
    dragClass = 'dragging',
    dropClass = 'drop-target',
    ghostClass = 'drag-ghost',
    animation = 200,
    showGhost = true,
    enableSnap = true,
    snapThreshold = 10
  } = options

  const isDragging = ref(false)
  const dragElement = ref(null)
  const ghostElement = ref(null)
  const dropTarget = ref(null)
  const dragOffset = ref({ x: 0, y: 0 })
  const dragPosition = ref({ x: 0, y: 0 })

  // 创建拖拽幽灵元素
  const createGhost = (element) => {
    if (!showGhost) return null

    const ghost = element.cloneNode(true)
    ghost.classList.add(ghostClass)
    ghost.style.position = 'fixed'
    ghost.style.pointerEvents = 'none'
    ghost.style.zIndex = '9999'
    ghost.style.opacity = '0.8'
    ghost.style.transition = `transform ${animation}ms cubic-bezier(0.4, 0, 0.2, 1)`
    
    // 添加拖拽动画效果
    ghost.style.transform = 'scale(0.95) rotate(2deg)'
    ghost.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.3)'
    
    document.body.appendChild(ghost)
    return ghost
  }

  // 更新幽灵元素位置
  const updateGhostPosition = (x, y) => {
    if (!ghostElement.value) return
    
    ghostElement.value.style.left = `${x}px`
    ghostElement.value.style.top = `${y}px`
  }

  // 查找可放置目标
  const findDropTarget = (x, y) => {
    const elements = document.elementsFromPoint(x, y)
    return elements.find(el => el.classList.contains('drop-zone'))
  }

  // 对齐到网格
  const snapToGrid = (value, gridSize) => {
    return Math.round(value / gridSize) * gridSize
  }

  // 处理拖拽开始
  const handleDragStart = (event, element, data) => {
    isDragging.value = true
    dragElement.value = element

    // 计算拖拽偏移量
    const rect = element.getBoundingClientRect()
    dragOffset.value = {
      x: event.clientX - rect.left,
      y: event.clientY - rect.top
    }

    // 创建幽灵元素
    ghostElement.value = createGhost(element)
    
    // 添加拖拽类
    element.classList.add(dragClass)
    
    // 设置拖拽数据
    if (event.dataTransfer) {
      event.dataTransfer.effectAllowed = 'move'
      event.dataTransfer.setData('text/plain', JSON.stringify(data))
    }

    // 初始位置
    updateGhostPosition(
      event.clientX - dragOffset.value.x,
      event.clientY - dragOffset.value.y
    )

    onDragStart(event, element, data)
  }

  // 处理拖拽移动
  const handleDragMove = (event) => {
    if (!isDragging.value) return

    let x = event.clientX - dragOffset.value.x
    let y = event.clientY - dragOffset.value.y

    // 启用网格对齐
    if (enableSnap) {
      x = snapToGrid(x, snapThreshold)
      y = snapToGrid(y, snapThreshold)
    }

    dragPosition.value = { x, y }
    updateGhostPosition(x, y)

    // 查找放置目标
    const target = findDropTarget(event.clientX, event.clientY)
    
    if (target !== dropTarget.value) {
      // 移除旧目标的高亮
      if (dropTarget.value) {
        dropTarget.value.classList.remove(dropClass)
      }
      
      // 高亮新目标
      if (target) {
        target.classList.add(dropClass)
      }
      
      dropTarget.value = target
    }

    onDragMove(event, dragPosition.value)
  }

  // 处理拖拽结束
  const handleDragEnd = (event) => {
    if (!isDragging.value) return

    const finalPosition = { ...dragPosition.value }
    const finalTarget = dropTarget.value

    // 清理拖拽状态
    if (dragElement.value) {
      dragElement.value.classList.remove(dragClass)
    }

    if (dropTarget.value) {
      dropTarget.value.classList.remove(dropClass)
    }

    // 移除幽灵元素（带动画）
    if (ghostElement.value) {
      ghostElement.value.style.transition = `all ${animation}ms cubic-bezier(0.4, 0, 0.2, 1)`
      ghostElement.value.style.opacity = '0'
      ghostElement.value.style.transform = 'scale(0.8)'
      
      setTimeout(() => {
        if (ghostElement.value && ghostElement.value.parentNode) {
          ghostElement.value.parentNode.removeChild(ghostElement.value)
        }
        ghostElement.value = null
      }, animation)
    }

    isDragging.value = false
    dragElement.value = null
    dropTarget.value = null

    onDragEnd(event, finalPosition, finalTarget)
  }

  // 处理放置
  const handleDrop = (event, dropData) => {
    event.preventDefault()
    
    let dragData = null
    try {
      dragData = JSON.parse(event.dataTransfer.getData('text/plain'))
    } catch (e) {
      console.error('Failed to parse drag data:', e)
    }

    onDrop(event, dragData, dropData, dragPosition.value)
  }

  // 处理拖拽进入
  const handleDragEnter = (event, element) => {
    event.preventDefault()
    element.classList.add(dropClass)
  }

  // 处理拖拽离开
  const handleDragLeave = (event, element) => {
    element.classList.remove(dropClass)
  }

  // 处理拖拽悬停
  const handleDragOver = (event) => {
    event.preventDefault()
    if (event.dataTransfer) {
      event.dataTransfer.dropEffect = 'move'
    }
  }

  // 绑定拖拽事件
  const bindDragEvents = (element, data) => {
    element.setAttribute('draggable', 'true')
    
    element.addEventListener('dragstart', (e) => handleDragStart(e, element, data))
    element.addEventListener('dragend', handleDragEnd)
  }

  // 绑定放置事件
  const bindDropEvents = (element, data) => {
    element.classList.add('drop-zone')
    
    element.addEventListener('dragenter', (e) => handleDragEnter(e, element))
    element.addEventListener('dragleave', (e) => handleDragLeave(e, element))
    element.addEventListener('dragover', handleDragOver)
    element.addEventListener('drop', (e) => handleDrop(e, data))
  }

  // 全局移动事件监听
  onMounted(() => {
    document.addEventListener('drag', handleDragMove)
  })

  onUnmounted(() => {
    document.removeEventListener('drag', handleDragMove)
    
    // 清理幽灵元素
    if (ghostElement.value && ghostElement.value.parentNode) {
      ghostElement.value.parentNode.removeChild(ghostElement.value)
    }
  })

  return {
    isDragging,
    dragPosition,
    dragElement,
    dropTarget,
    bindDragEvents,
    bindDropEvents,
    handleDragStart,
    handleDragMove,
    handleDragEnd,
    handleDrop
  }
}

/**
 * 拖拽排序功能
 */
export function useDragSort(list, options = {}) {
  const {
    onSort = () => {},
    direction = 'vertical', // vertical | horizontal
    animation = 200
  } = options

  const dragIndex = ref(-1)
  const dropIndex = ref(-1)

  const handleSortStart = (index) => {
    dragIndex.value = index
  }

  const handleSortOver = (index) => {
    if (dragIndex.value === -1) return
    dropIndex.value = index
  }

  const handleSortEnd = () => {
    if (dragIndex.value === -1 || dropIndex.value === -1) return
    if (dragIndex.value === dropIndex.value) {
      dragIndex.value = -1
      dropIndex.value = -1
      return
    }

    // 执行排序
    const newList = [...list.value]
    const dragItem = newList[dragIndex.value]
    newList.splice(dragIndex.value, 1)
    newList.splice(dropIndex.value, 0, dragItem)
    
    list.value = newList
    onSort(newList, dragIndex.value, dropIndex.value)

    dragIndex.value = -1
    dropIndex.value = -1
  }

  return {
    dragIndex,
    dropIndex,
    handleSortStart,
    handleSortOver,
    handleSortEnd
  }
}

/**
 * 拖拽调整大小
 */
export function useDragResize(options = {}) {
  const {
    onResize = () => {},
    minWidth = 100,
    minHeight = 100,
    maxWidth = Infinity,
    maxHeight = Infinity,
    aspectRatio = null
  } = options

  const isResizing = ref(false)
  const resizeDirection = ref('')
  const startSize = ref({ width: 0, height: 0 })
  const startPosition = ref({ x: 0, y: 0 })
  const currentSize = ref({ width: 0, height: 0 })

  const handleResizeStart = (event, element, direction) => {
    isResizing.value = true
    resizeDirection.value = direction
    
    const rect = element.getBoundingClientRect()
    startSize.value = { width: rect.width, height: rect.height }
    startPosition.value = { x: event.clientX, y: event.clientY }
    currentSize.value = { ...startSize.value }
  }

  const handleResizeMove = (event) => {
    if (!isResizing.value) return

    const deltaX = event.clientX - startPosition.value.x
    const deltaY = event.clientY - startPosition.value.y

    let newWidth = startSize.value.width
    let newHeight = startSize.value.height

    // 根据方向计算新尺寸
    if (resizeDirection.value.includes('e')) {
      newWidth = startSize.value.width + deltaX
    }
    if (resizeDirection.value.includes('w')) {
      newWidth = startSize.value.width - deltaX
    }
    if (resizeDirection.value.includes('s')) {
      newHeight = startSize.value.height + deltaY
    }
    if (resizeDirection.value.includes('n')) {
      newHeight = startSize.value.height - deltaY
    }

    // 应用约束
    newWidth = Math.max(minWidth, Math.min(maxWidth, newWidth))
    newHeight = Math.max(minHeight, Math.min(maxHeight, newHeight))

    // 保持宽高比
    if (aspectRatio) {
      if (resizeDirection.value.includes('e') || resizeDirection.value.includes('w')) {
        newHeight = newWidth / aspectRatio
      } else {
        newWidth = newHeight * aspectRatio
      }
    }

    currentSize.value = { width: newWidth, height: newHeight }
    onResize(currentSize.value)
  }

  const handleResizeEnd = () => {
    isResizing.value = false
    resizeDirection.value = ''
  }

  onMounted(() => {
    document.addEventListener('mousemove', handleResizeMove)
    document.addEventListener('mouseup', handleResizeEnd)
  })

  onUnmounted(() => {
    document.removeEventListener('mousemove', handleResizeMove)
    document.removeEventListener('mouseup', handleResizeEnd)
  })

  return {
    isResizing,
    resizeDirection,
    currentSize,
    handleResizeStart,
    handleResizeMove,
    handleResizeEnd
  }
}

